﻿using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Threading;
using AEM.Utils;

namespace AEM
{
    /// <summary>
    /// App.xaml 的交互逻辑
    /// </summary>
    public partial class App : Application
    {
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly;
            Utils.LanguageHelper.LoadLanguageFile();
#if DEBUG
            ConsoleManager.Show();
#endif
            //设置应用程序工作目录为EXE文件所在目录
            System.IO.Directory.SetCurrentDirectory(System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath));
            Debug.WriteLine("程序工作目录现在是:" + System.IO.Directory.GetCurrentDirectory());
            Process instance = RunningInstance();
            if (instance == null)
            {

                var timer = new DispatcherTimer { Interval = TimeSpan.FromMinutes(5) };
                timer.Tick += (s, ev) => FulshMemor();
                timer.Start();

                Debug.WriteLine("ErrCallback开始" + "当前时间{0}||{1}毫秒", DateTime.Now.ToString(), DateTime.Now.Millisecond.ToString());//为了看一下启动时间
                AEM.Utils.GConfig.ErrCallback = ErrCallback;
                Debug.WriteLine("ErrCallback结束" + "当前时间{0}||{1}毫秒", DateTime.Now.ToString(), DateTime.Now.Millisecond.ToString());//为了看一下启动时间
                Splasher.Splash = new SplashScreen();
                Application currApp = Application.Current;
                currApp.StartupUri = new Uri("Login.xaml", UriKind.RelativeOrAbsolute);
            }
            else {
                //There is another instance of this process.   
                HandleRunningInstance(instance);
                MessageBox.Show("AEM已被启动，请留意系统状态栏", "软件被重复启动");
                Application.Current.Shutdown(0);
            }
        }

        public static void ErrCallback(string message, string title, bool isNeedCloseApp, Exception exception)
        {
            //写bugreport
            try
            {
                AEM.Utils.BubReport br = new AEM.Utils.BubReport();
                br.Level = isNeedCloseApp ? "严重" : "未处理的异常";
                br.message = title;
                StackTrace st = exception != null ? new StackTrace(exception) : new StackTrace(true);
                br.tracert = st.ToString();
                br.softLog = Log.getRecentLog();
                br.Report();
            }
            catch (Exception ex)
            {
                Debug.WriteLine("发送错误报告失败" + ex.ToString());
            }
            if (!isNeedCloseApp) return;
            if (string.IsNullOrEmpty(title)) title = "发生严重的错误";
            System.Windows.Forms.DialogResult dr = System.Windows.Forms.MessageBox.Show(message, title, System.Windows.Forms.MessageBoxButtons.AbortRetryIgnore, System.Windows.Forms.MessageBoxIcon.Error, System.Windows.Forms.MessageBoxDefaultButton.Button1);
            if (dr == System.Windows.Forms.DialogResult.Abort) Environment.Exit(-9);
            else if (dr == System.Windows.Forms.DialogResult.Ignore) { }
            else if (dr == System.Windows.Forms.DialogResult.Retry) { }
        }


        /// <summary>
        /// 获取本文件已运行的实例
        /// </summary>
        /// <returns></returns>
        private static Process RunningInstance()
        {
            Process current = Process.GetCurrentProcess();
            Process[] processes = Process.GetProcessesByName(current.ProcessName);
            //Loop   through   the   running   processes   in   with   the   same   name   
            foreach (Process process in processes)
            {
                //Ignore   the   current   process   
                if (process.Id != current.Id)
                {
                    //Make   sure   that   the   process   is   running   from   the   exe   file.   

                    if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == current.MainModule.FileName)
                    {
                        //Return   the   other   process   instance.   
                        return process;
                    }
                }
            }
            //No   other   instance   was   found,   return   null. 
            return null;
        }

        [DllImport("kernel32.dll")]
        public static extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max);
        /// <summary>
        /// 释放内存
        /// </summary>
        public void FulshMemor()
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
            if (Environment.OSVersion.Platform == PlatformID.Win32NT)
            {
                SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
            }
        }

        private static void HandleRunningInstance(Process instance)
        {
            //Make   sure   the   window   is   not   minimized   or   maximized   
            ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL);
            //Set   the   real   intance   to   foreground   window
            SetForegroundWindow(instance.MainWindowHandle);
        }

        [DllImport("User32.dll")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
        [DllImport("User32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);
        private const int WS_SHOWNORMAL = 1;
    }
}
